import { BaseService } from '@/core/base.service';
import { Process, Processor } from '@nestjs/bull';
import { Job } from 'bull';
import { AutoSaleStatusEnum, TokenLogTypeEnum, TokenStatusEnum } from '@/enums';
import dayjs from 'dayjs';
import { random, sleep } from 'radash';
import { halt } from '@/utils';
import { Logger } from '@nestjs/common';

@Processor('autosale')
export class AutosaleProcessor extends BaseService {
  @Process('sale')
  async sale(job: Job) {
    const time = dayjs().format('YYYY-MM-DD HH:mm:ss');
    const await_lock = await this.redis.exists(
      'bull:autosale:repeat:await_lock',
    );
    if (await_lock) {
      Logger.debug('!!!!!!!!!!!!!!!!!!自动挂售:挂售进行中' + await_lock);
      return {};
    }
    await this.redis.setex('bull:autosale:repeat:await_lock', 60, time);

    const list = await this.prisma.assetAutoSale.findMany({
      where: {
        status: AutoSaleStatusEnum.RUNNING,
      },
    });

    if (list.length > 0) {
      for (const item of list) {
        // Logger.debug(`${item.assetId}:开始挂售`);

        if (!item.isIgnore) {
          // 不忽略用户挂单
          const userSaleCount = await this.prisma.token.count({
            where: {
              assetId: item.assetId,
              ownerId: { not: item.sellerId },
              status: TokenStatusEnum.ON_SALE,
            },
          });

          if (userSaleCount > 0) {
            Logger.debug(
              `${item.assetId}:不忽略用户挂单，用户挂单>0，挂售下一个藏品`,
            );
            // Logger.debug(`${item.assetId}:结束挂售`);
            continue;
          }
        }

        // const currentTime = dayjs();
        // Logger.debug('当前时间' + currentTime.format('YYYY-MM-DD HH:mm:ss'));

        const sNextWait = await this.redis.exists(
          'bull:autosale:repeat:sale:' + item.id + ':sleep',
        );
        if (sNextWait) {
          const ttl = await this.redis.ttl(
            'bull:autosale:repeat:sale:' + item.id + ':sleep',
          );
          // 如果有下一次上架时间
          Logger.debug(`${item.id}:上架时间未到达，剩余${ttl}s`);
          // Logger.debug(`${item.assetId}:结束挂售`);
          continue;
          // return {};
        } else {
          // 如果没有下一次上架时间，生成一个时间
          Logger.debug(`${item.id}:无上架等待时间，查询同时上架数量`);
          const lockingCount = await this.prisma.token.count({
            where: {
              status: TokenStatusEnum.ON_SALE,
              ownerId: item.sellerId,
              assetId: item.assetId,
            },
          });
          if (lockingCount >= item.onceTime) {
            Logger.debug(
              `${item.assetId}:同时存在数量${lockingCount}≥设定值${item.onceTime}，挂售下一个藏品`,
            );
            // Logger.debug(`${item.assetId}:结束挂售`);
            continue;
          }
          Logger.debug(
            `${item.id}:########################开始上架########################`,
          );
          const saleTokenId = await this.redis.spop(
            'autosale:' + item.id + ':queue',
          );
          if (saleTokenId == null) {
            Logger.debug(`${item.id}:挂售队列为空，结束挂售`);
            await this.prisma.assetAutoSale.update({
              where: {
                id: item.id,
              },
              data: {
                status: AutoSaleStatusEnum.COMPLETED,
              },
            });
            continue;
          }

          Logger.debug(`${item.id}:资产ID：${saleTokenId}`);
          // 开始上架，并生成下次上架时间
          try {
            await this.prisma.token.update({
              where: {
                id: Number(saleTokenId),
                status: TokenStatusEnum.HOLD,
                ownerId: item.sellerId,
                assetId: item.assetId,
              },
              data: {
                status: TokenStatusEnum.ON_SALE,
                price: random(Number(item.minPrice), Number(item.maxPrice)),
                sellerId: item.sellerId,
              },
            });
          } catch (error) {
            Logger.debug(
              `${item.id}:########################上架失败########################`,
            );
            // Logger.debug(`${item.assetId}:结束挂售`);
            continue;
          }

          Logger.debug(
            `${item.id}:########################上架成功########################`,
          );

          Logger.debug(`${item.id}:设置下次上架时间`);
          await this.redis.setex(
            'bull:autosale:repeat:sale:' + item.id + ':sleep',
            random(5, 10),
            1,
          );

          const waitTime = item.waitTime + random(5, 10);
          Logger.debug(
            `${item.assetId}:设置${item.id}挂售维持时间${waitTime}s`,
          );
          await this.redis.setex(
            `autosale:${item.id}:wait_down:${saleTokenId}`,
            waitTime,
            1,
          );
          // Logger.debug(`${item.assetId}:结束挂售`);
        }
      }
    } else {
      Logger.debug(`无挂售任务`);
    }
    await this.redis.del('bull:autosale:repeat:await_lock');
    return {};
  }
}
